home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_069 / monproc / monproc.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  249 lines

  1. /* monproc.c    - monitor amigados process packet activity.
  2.  *
  3.  * Phillip Lindsay (c) 1987 Commodore-Amiga, Inc.
  4.  *
  5.  */
  6.  
  7. #include <exec/types.h>
  8. #include <exec/nodes.h>
  9. #include <exec/lists.h>
  10. #include <exec/memory.h>
  11. #include <exec/ports.h>
  12. #include <exec/tasks.h>
  13. #include <exec/semaphores.h>
  14. #include <libraries/dos.h>
  15. #include <libraries/dosextens.h>
  16. #include <libraries/filehandler.h>
  17.  
  18. #ifdef MANX
  19. #include <functions.h>
  20. #else
  21. #define index stpchr    /* can you say "ANSI STANDARD"...I knew you could... */
  22. #endif
  23. #include <stdio.h>
  24.  
  25. /* constants */
  26.  
  27. #define ONE            1L
  28.  
  29. /* AmigaDOS uses task signal bit 8 for message signaling */
  30. #define DOS_SIGNAL        8
  31. #define DOS_MASK        ( ONE << DOS_SIGNAL )
  32.  
  33. /* referenced globals */
  34. extern void         getprocs(),freeprocs(),givepkt();
  35. void             memfill();
  36. extern struct DosLibrary *DOSBase;
  37. struct Message         *packetwait();
  38. LONG             pw();    /* this the asm stub that calls packetwait() */
  39.  
  40. /* global data structures */
  41. struct MsgPort         *deviceid;
  42. struct Process         *memyselfNi;
  43. ULONG               mymask;
  44. struct SignalSemaphore canreturn;
  45. struct Message         *mymess;
  46.  
  47.  
  48. main()
  49. {
  50.  struct   List            procs;
  51.  struct   Node            *proc;
  52.  register struct Process    *devproc;
  53.  register struct DosPacket    *pkt;
  54.  BYTE                mypri;    
  55.  register ULONG            waitmask,signals,oldpktwait;
  56.  LONG                mysignal;
  57.  ULONG                count,choice;
  58.  UBYTE                processname[81];
  59.  
  60.  puts("MONPROC - monitor AmigaDOS process packet activity.\n");
  61.  
  62.  memyselfNi = (struct Process *) FindTask(NULL);
  63.  NewList(&procs);     /* initialize list header */
  64.  getprocs(&procs);    /* fill list with "active" devices */
  65.  
  66.  if(procs.lh_TailPred == &procs) /* list empty (should never happen) */
  67.   {
  68.    puts("No processes.");
  69.    exit(0);
  70.   }
  71.  
  72. /*
  73.  * I am assuming that process list won't change. This is for hackers only.
  74.  */
  75.  do
  76.   {
  77.    puts("Enter NUMBER for process to monitor:"); 
  78.    puts("Pick# Process  MsgPort  Name");    
  79.    for(count = 1,proc = procs.lh_Head;proc->ln_Succ;proc=proc->ln_Succ,count++)
  80.      printf("%4ld. %08lx %08lx %s\n",count,
  81.          ((struct Process *)proc->ln_Name),
  82.          &(((struct Process *)proc->ln_Name)->pr_MsgPort),
  83.          ((struct Process *)proc->ln_Name)->pr_Task.tc_Node.ln_Name);
  84.    printf("\nNUMBER: ");
  85.    fflush(stdout);  
  86.   } while( scanf("%ld",&choice) == EOF ) ;
  87.  
  88.  
  89.  if(!choice || choice >= count)
  90.   {
  91.    puts("Operation aborted.");
  92.    freeprocs(&procs);
  93.    exit(0);
  94.   }
  95.  
  96. /* what did he/she pick? */
  97.   for(count = 1,proc = procs.lh_Head;proc->ln_Succ;proc=proc->ln_Succ,count++)
  98.    if(choice == count)
  99.     {
  100.      devproc = (struct Process *) proc->ln_Name;
  101.      break;
  102.     }
  103.  
  104. /* we don't need our process list anymore */
  105.  freeprocs(&procs);
  106.  
  107. /* make a copy of the process name */
  108.  strcpy(processname,devproc->pr_Task.tc_Node.ln_Name);
  109.  
  110. /* get process msgport of process we will be monitoring */
  111.  deviceid = &devproc->pr_MsgPort;
  112.  
  113. /* grab a signal for task intercommunication */
  114.  mysignal = (LONG) AllocSignal(-1L);
  115.  if(mysignal == -1)
  116.   {
  117.    puts("Can't allocate a task signal.");
  118.    exit(0);
  119.   }
  120.  
  121.  mymask = ONE << mysignal;
  122.  
  123.  waitmask = SIGBREAKF_CTRL_C | mymask;
  124.  
  125. /* initialize our semaphore */
  126.  memfill(&canreturn,(ULONG)sizeof(canreturn),0L);
  127.  InitSemaphore(&canreturn);
  128.  
  129.  Forbid();
  130.  mypri = devproc->pr_Task.tc_Node.ln_Pri;
  131.  Permit();
  132.  
  133. /* make sure our priority is greater than the device task  */
  134.  SetTaskPri(memyselfNi, (ULONG)(mypri+1) ); 
  135.  
  136.  puts("Waiting for messages...[CTRL_C to quit monitoring...]"); 
  137.  
  138.  /* install our packet wait function */
  139.  Forbid();
  140.  oldpktwait          = (ULONG) devproc->pr_PktWait;
  141.  devproc->pr_PktWait = (APTR)  pw;
  142.  Permit();
  143.  
  144. /*
  145.  * I am using semaphores to control the monitoring of the handler's packets.
  146.  * There is probably a hundred better ways of doing this. I just went with
  147.  * what first came to mind. Since I am a higher priority than the handler...
  148.  * Once I am awake I will obtain the semaphore before the lower priority
  149.  * task has a chance...I will give it back to him once I am done with the
  150.  * packet data structure. 
  151.  */
  152. do 
  153.   {
  154.  
  155.    signals = (ULONG) Wait(waitmask); 
  156.    ObtainSemaphore(&canreturn);    
  157.  
  158.    if(signals & mymask)             /* did the packetwait code signal us? */
  159.     {                               /* yes, let's boogie...             */
  160.      pkt = (struct DosPacket *) mymess->mn_Node.ln_Name; /* get packet address */
  161.      printf("%s: ",processname);     
  162.      givepkt(pkt);
  163.     } 
  164.  
  165.    ReleaseSemaphore(&canreturn);
  166.  
  167.   } while(!(signals & SIGBREAKF_CTRL_C)); 
  168.  
  169.  /* remove our packet wait function and install previous value */
  170.  Forbid();
  171.  devproc->pr_PktWait = (APTR) oldpktwait;
  172.  Permit();
  173.  SetTaskPri(memyselfNi,0L);
  174.  puts("\nThere is no safe way to leave since the process is waiting in");
  175.  puts("our installed code. We have de-installed ourselves, but you should");
  176.  puts("be certain that the process received a packet AFTER we have been");
  177.  puts("de-installed. Press CTRL-E if you are certain this has happened.");
  178.  Wait(SIGBREAKF_CTRL_E);
  179.  FreeSignal(mysignal);
  180.  puts("All done.");
  181.  
  182. } /* end of main() */
  183.  
  184.  
  185. /**
  186.  ** local subroutines 
  187.  **/
  188.  
  189. /*
  190.  * packetwait() ... Waits for a message to arrive at your port and 
  191.  *   returns it to you.
  192.  */
  193. struct Message *packetwait()
  194. {
  195. #ifdef MANX    /* if MANX make sure we can see our data */
  196.  geta4();
  197. #endif
  198.  /* wait for packet */
  199.  SetSignal(FALSE,DOS_MASK);    /* clear sigbit 8 */
  200.  while( !(mymess = (struct Message *) GetMsg(deviceid)) )  Wait(DOS_MASK);
  201.  Signal(memyselfNi,mymask); /* Wake up monitoring task he will grab the data */
  202.  ObtainSemaphore(&canreturn); /* we get this guy when we CAN return */    
  203.  ReleaseSemaphore(&canreturn);
  204.  
  205.  return(mymess); 
  206.  
  207. /*
  208.  * memfill() - fill memory with supplied byte value for "size" bytes
  209.  */
  210. void memfill(source,size,value)
  211. UBYTE *source;
  212. ULONG size;
  213. UBYTE value;    
  214. {
  215.  register UBYTE *msource=source,
  216.         mvalue=value;
  217.  register ULONG msize=size;
  218.  
  219.  if(msize)
  220.   {
  221.    do
  222.     {
  223.      --msize;
  224.      msource[msize] = mvalue;
  225.     } while(msize);
  226.  
  227.   }
  228. }
  229.  
  230. /*
  231.  * This code stub has been known to save lives... 
  232.  */
  233.  
  234. #if MANX     
  235. #asm
  236.     XREF _packetwait        
  237.  
  238.      XDEF _pw
  239. _pw:
  240.     movem.l a2/a3/a4,-(sp)
  241.     jsr _packetwait
  242.     movem.l (sp)+,a2/a3/a4
  243.     rts
  244. #endasm
  245. #endif
  246.  
  247. /* end of procdev.c */
  248.